<template>
  <div class="department-container">
    <div class="app-container">
      <!-- 顶部 - 卡片&按钮 -->
      <el-card class="box-card titleCom">
        <!-- 传递两个参数:
        type: 判断是创建的页面权限还是子菜单权限
        id: 将当前项的id作为参数传给事件处理函数, 用于给对应id的数据添加子数据
        type: 1 代表当前创建的是页面权限
        pid: '0' 代表当前项是一级菜单 -->
        <el-button type="primary" size="medium" round plain @click="addPermissionBtn(1, '0', 'add')">添加权限</el-button>
        <el-button type="primary" size="medium" round plain @click="test">添加新路由</el-button>
      </el-card>

      <!-- 表格组件 -->
      <!-- 为表格组件的每一项添加一个 row-key 属性作为唯一值 -->
      <el-card class="box-card">
        <el-table
          :data="tableData"
          row-key="id"
          style="width: 100%"
        >
          <el-table-column
            prop="name"
            label="名称"
            width="180"
          />
          <el-table-column
            prop="code"
            label="标识"
            width="180"
          />
          <el-table-column
            prop="description"
            label="描述"
          />
          <el-table-column
            fixed="right"
            label="操作"
            width="210"
          >
            <template slot-scope="scoped">
              <!-- 传递三个参数:
              type: 判断是创建的页面权限还是子菜单权限
              pid: 将当前项的pid作为参数传给事件处理函数, 用于判断, 给对应id的数据添加子数据
              type: 2 代表当前创建的是子菜单(二级菜单)权限
              pid: 此处传递的是当前项的id;  将当前项的 id 作为 pid , 代表创建的是当前项的子数据
              因为子数据的 pid 与 父菜单的 id 相对相应
              所以, 如果我们点击的是一级菜单的新增, 那么就将一级菜单对应的 id 作为 二级菜单的 pid 传递参数
              editOrAdd: 'add' 'isEdit' 根据点击按钮时传递的对应参数判断是新增还是编辑
              -->
              <el-button
                v-if="scoped.row.type === 1"
                type="primary"
                size="small"
                plain
                @click="addPermissionBtn(2, scoped.row.id, 'add')"
              >添加</el-button>
              <el-button
                type="success"
                size="small"
                plain
                @click="addPermissionBtn(scoped.row.type, scoped.row.id, 'edit')"
              >编辑</el-button>
              <!-- 根据作用域插槽获取的当前数据中, children数组长度是否W为0, 判断当前项有没有子数据 -->
              <!-- 如果有就隐藏删除按钮, 如果没有就显示删除按钮 -->
              <el-button
                v-if="scoped.row.children.length === 0"
                type="warning"
                size="small"
                plain
                @click="deleteBtn(scoped.row.id)"
              >删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-card>

      <!-- 添加权限 - 弹出框 dialog -->
      <el-dialog
        :title="isEdit ? '编辑权限' : '新增权限'"
        :visible.sync="dialogVisible"
        width="50%"
        :show-close="false"
        :close-on-click-modal="false"
        :close-on-press-escape="false"
        @close="dialogClose"
      >
        <el-form ref="formRef" :model="formData" label-width="80px">
          <el-form-item label="权限名称">
            <el-input v-model="formData.name" />
          </el-form-item>
          <el-form-item label="权限标识">
            <el-input v-model="formData.code" />
          </el-form-item>
          <el-form-item label="权限描述">
            <el-input v-model="formData.description" />
          </el-form-item>
          <el-form-item label="是否启用" prop="delivery">
            <el-switch
              v-model="formData.enVisible"
              active-text="启用"
              inactive-text="不启用"
              active-color="#13ce66"
              inactive-color="#ff4949"
              active-value="1"
              inactive-value="2"
            />
          </el-form-item>
          <el-form-item>
            <el-button @click="dialogVisible = false">取消</el-button>
            <el-button type="primary" @click="onSubmit">{{ isEdit ? '立即编辑' : '立即添加' }}</el-button>
          </el-form-item>
        </el-form>
      </el-dialog>
    </div>
  </div>
</template>

<script>
import { addPermissionRequest, deletePermissionByIdRequest, getPermissionRequest, getPermissionByIdRequest, updatePermissionByIdRequest } from '@/api/permission'
import { transformListToTree2 } from '@/utils/index'
export default {
  data() {
    return {
      // 表格数据初始化
      tableData: [],
      // 表单数据初始化
      formData: {
        name: '',
        code: '',
        description: '',
        enVisible: '', // 权限是否启用
        type: 0, // 1: 页面权限, 2: 子按钮权限
        pid: '' // 一级菜单
      },
      // 控制模态框是否关闭
      dialogVisible: false,
      // 当前状态是否为编辑
      isEdit: false
    }
  },
  created() {
    this.getPermission() // 渲染
  },
  methods: {
    // ^ ==================== 请求 ====================
    // 请求 - 获取所有权限点列表
    async getPermission() {
      try {
        const res = await getPermissionRequest()
        if (res.success) {
          // 由于表格需要渲染树形结构, 所以需要将平铺数据转换为树形结构, 渲染时才能出现折叠按钮
          // 使用递归实现平铺数据转树形结构, 传递两个参数, 第一个参数平铺数组, 第二个参数是一级菜单pid, 此处为字符串'0'
          this.tableData = transformListToTree2(res.data, '0')
        } else {
          this.$message.error('获取所有权限点失败!')
        }
      } catch (error) {
        console.log('获取所有权限点失败', error)
      }
    },
    // 请求 - 添加权限点
    async addPermission() {
      try {
        const res = await addPermissionRequest(this.formData)
        if (res.success) {
          this.$message.success('添加权限点成功!')
          this.dialogVisible = false // 关闭模态框
          this.getPermission() // 重新渲染
        } else {
          this.$message.error('添加权限点失败!')
        }
      } catch (error) {
        console.log('新增权限失败', error)
      }
    },
    // 请求 - 删除权限点
    async deletePermissionById(id) {
      try {
        const res = await deletePermissionByIdRequest(id)
        if (res.success) {
          this.$message.success('删除权限点成功!')
          this.getPermission() // 重新渲染
        } else {
          this.$message.error('删除权限点失败!')
        }
      } catch (error) {
        console.log('删除权限点失败', error)
      }
    },
    // 请求 - 获取权限点详情
    async getPermissionById(id) {
      try {
        const res = await getPermissionByIdRequest(id)
        if (res.success) {
          console.log(res)
          this.formData = res.data // 将请求获取的数据赋值给表单数据
        } else {
          this.$message.error('获取权限点详情失败!')
        }
      } catch (error) {
        console.log('获取权限点详情失败!', error)
      }
    },
    // 请求 - 更新权限点详情
    async updatePermissionById() {
      try {
        const res = await updatePermissionByIdRequest(this.formData)
        if (res.success) {
          this.$message.success('更新权限点详情成功')
          this.success() // 调用成功事件
        } else {
          this.$message.error('更新权限点详情失败')
        }
      } catch (error) {
        console.log('更新权限点详情失败!', error)
      }
    },

    // ^ ==================== 事件 ====================
    // 事件 - 添加权限按钮
    // 点击添加权限按钮时: 点击对应按钮, 就会接收不同的参数
    // 如果点击的是页面权限的添加按钮, 就代表是点击一级菜单来添加二级菜单
    // 此时直接将 一级菜单对应数据的 id , 作为二级菜单的 pid 进行传参并接收, 代表二级菜单时一级菜单的子菜单
    // 第三个参数用来判断点击的是编辑还是新增, 如果接受的参数是 'add' 代表是新增, 就将 isEdit 改为 false
    addPermissionBtn(type, id, editOrAdd) {
      // 判断更新还是新增
      if (editOrAdd === 'edit') {
        this.isEdit = true // 将状态改为编辑
        this.getPermissionById(id) // 调用请求函数进行数据回显, 传参
      } else {
        this.isEdit = false
      }
      this.dialogVisible = true // 开启模态框
      this.formData.type = type // 获取当前点击的是页面权限还是菜单权限
      this.formData.pid = id
    },
    // 事件 - 表单提交按钮
    // 编辑新增按钮为同一个时, 需要进行区分
    onSubmit() {
      if (this.isEdit) {
        this.updatePermissionById() // 更新
      } else {
        this.addPermission() // 添加 - 请求
      }
    },
    // 事件 - 删除按钮
    deleteBtn(id) {
      this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.deletePermissionById(id) // 调用删除接口
      }).catch(() => {
        this.$message.info('已取消删除')
      })
    },
    // 模态框关闭事件
    dialogClose() {
      this.$refs.formRef.resetFields() // 清空表单
      this.formData = this.$options.data.call(this).formData // 清空表单数据
    },
    // 事件 - 操作成功, 渲染页面, 关闭模态框
    success() {
      this.dialogVisible = false
      this.getPermission()
    },
    // 动态路由权限 - 动态添加路由
    test() {
      this.$router.addRoutes([
        {
          path: '/demo',
          component: () => import('@/views/demo.vue')
        }
      ])
    }
    // RBAC 权限系统: 核心是通过 角色来连接用户和权限
    // 每个角色都有自己的一些权限列表, 比如管理员角色, 包含有50个页面, 10个按钮的权限
    // 比如普通角色, 只有5个页面的权限, 0 个按钮权限
  }
}
</script>

<style lang="scss">
.el-card.titleCom {
  text-align: right !important;
  margin-bottom: 15px !important;
}
</style>

